package client;

import pojo.*;
import util.StreamUtil;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;

public class Client {
    private String IP = "127.0.0.1";
    private Socket socket;
    private ObjectInputStream inputStream;
    private ObjectOutputStream outputStream;
    private Scanner scanner;
    private StreamUtil<ClientMessage,ServerMessage> streamUtil;
    private String myName;

    public Client() throws IOException, ClassNotFoundException, InterruptedException {
        socket = new Socket(IP,10086);
        outputStream = new ObjectOutputStream(socket.getOutputStream());
        inputStream = new ObjectInputStream(socket.getInputStream());
        streamUtil = new StreamUtil<>(ServerMessage.class);
        scanner = new Scanner(System.in);
        regist();
        System.out.println("注册成功，获得1000元的初始资金");
        System.out.println("### 游戏客户端初始化完成，正在等待服务器开始游戏(在线玩家人数>=2，游戏才会开始) ###");
        while(true){
            ServerMessage serverMessage = streamUtil.read(inputStream);
            switch (serverMessage.getType()){
                case BEGIN:
                    System.out.println();
                    printMoney(serverMessage.getPeople());
                    System.out.println("游戏开始，等待系统发牌");
                    break;
                case READY:
                    ready(serverMessage);
                    break;
                case DECISION:
                    decision(serverMessage);
                    break;
                case WINNER:
                    System.out.println();
                    printAllPoke(serverMessage.getPeople());
                    System.out.println();
                    System.out.println("恭喜"+serverMessage.getPeople().get(serverMessage.getWinner()).getName()+"获得游戏胜利");
                    break;
                case REJECT:
                    System.out.println("服务器拒绝您的连接请求，最多同时5个人在线");
            }
        }
    }


    private void printPoke(List<Person> gamers,int gamerNumber){
        System.out.println("-------------------------------------------------------------------");
        for (int i=0 ; i< gamers.size() ; i++){
            List<PokeEnum> pokeList = gamers.get(i).getPokeList();
            if (i == gamerNumber){
                System.out.println();
                System.out.print(gamers.get(i).getName()+"    : ");
                for (PokeEnum pokeEnum : pokeList) {
                    System.out.print(pokeEnum.getColor()+pokeEnum.getName()+"  ");
                }
            }else {
                System.out.println();
                System.out.print(gamers.get(i).getName()+"    : ");
                if (gamers.get(i).isAbandon()){
                    System.out.print("该玩家已弃牌");
                }else {
                    System.out.print("****  ");
                    for (int j=1 ;j<pokeList.size();j++){
                        System.out.print(pokeList.get(j).getColor()+pokeList.get(j).getName()+"  ");
                    }
                }
            }
        }
    }

    private void printAllPoke(List<Person> gamers){
        for (int i=0 ; i< gamers.size() ; i++){
            List<PokeEnum> pokeList = gamers.get(i).getPokeList();
            System.out.println();
            System.out.print(gamers.get(i).getName()+"    : ");
            for (int j=0 ;j<pokeList.size();j++){
                System.out.print(pokeList.get(j).getColor()+pokeList.get(j).getName()+"  ");
            }
            if (gamers.get(i).isAbandon()){
                System.out.print("该玩家弃牌");
            }
        }
    }

    private void ready(ServerMessage  serverMessage) throws IOException {
        boolean ready = false;
        while (!ready){
            System.out.println();
            System.out.println("游戏即将开始，请输入\"ready\"并按回车进行准备");
            String input = scanner.nextLine();
            if ("ready".equals(input)){
                ready = true;
            }
        }
        ClientMessage clientMessage = new ClientMessage();
        clientMessage.setReady(true);
        streamUtil.write(outputStream,clientMessage);
        if (serverMessage.getMoneyLeft() == 0){
            System.out.println();
            System.out.println("###服务器发现您金额不足，为了方便测试，自动为您充值1000元###");
            System.out.println();
        }
        System.out.println("已准备，等待其他玩家准备后游戏开始");
    }

    private void decision(ServerMessage serverMessage) throws IOException {
        printPoke(serverMessage.getPeople(),serverMessage.getGamerNumber());
        System.out.println();
        System.out.println();
        boolean finish = false;
        while(!finish){
            finish = true;
            if (serverMessage.getMoneyLeft() == 0){
                System.out.println("您已经梭哈，无需选择，系统为您自动跟注");
                ClientMessage decisionMessage = new ClientMessage();
                decisionMessage.setDecision(DecisionEnum.SUOHA);
                streamUtil.write(outputStream,decisionMessage);
                continue;
            }

            if (serverMessage.getDecisionMaker() == serverMessage.getGamerNumber()){
                System.out.println();
                System.out.println("由您开始决定下注:");
                System.out.println("a.下注    b.放弃");
                String input = scanner.nextLine();
                if ("a".equals(input) || "A".equals(input)){
                    System.out.println();
                    System.out.println("请输入下注金额，下注范围为0-"+serverMessage.getMoneyLeft());
                    input = scanner.nextLine();
                    int cost = 0 ;
                    try {
                        cost = Integer.valueOf(input);
                        if (cost <0 || cost>serverMessage.getMoneyLeft()){
                            throw new RuntimeException("金额超出范围");
                        }
                        ClientMessage decisionMessage = new ClientMessage();
                        decisionMessage.setDecision(DecisionEnum.MAKE_DECISION);
                        decisionMessage.setCost(cost);
                        streamUtil.write(outputStream,decisionMessage);
                        System.out.println();
                        System.out.println("下注成功");
                    }catch (Exception ex){
                        System.out.println("###只能输入整数，或者输入的数据超过金额范围，请重新输入###");
                        finish = false;
                    }
                }else if("b".equals(input) || "B".equals(input)){
                    ClientMessage decisionMessage = new ClientMessage();
                    decisionMessage.setDecision(DecisionEnum.ABANDON);
                    streamUtil.write(outputStream,decisionMessage);
                    System.out.println("成功放弃，请等待游戏结束");
                }else {
                    System.out.println("###您的输入有误，请重新输入###");
                    finish = false;
                }
            }else {
                if (serverMessage.getPeople().get(serverMessage.getDecisionMaker()).isSuoha()){
                    Person decisionMaker = serverMessage.getPeople().get(serverMessage.getDecisionMaker());
                    System.out.println(serverMessage.getPeople().get(serverMessage.getDecisionMaker()).getName()+"已梭哈，梭哈总额为"+decisionMaker.getMoney()+"元。");
                }else {
                    System.out.println(serverMessage.getPeople().get(serverMessage.getDecisionMaker()).getName()+"下注"+serverMessage.getCost()+"元。");
                }
                System.out.println("您剩余"+serverMessage.getMoneyLeft()+"元。");
                System.out.println("a.跟注    b.加注    c.放弃");
                String input = scanner.nextLine();
                if ("a".equals(input) || "A".equals(input)){
                    ClientMessage decisionMessage = new ClientMessage();
                    if (serverMessage.getMoneyLeft() <= serverMessage.getCost()){
                        decisionMessage.setDecision(DecisionEnum.SUOHA);
                        decisionMessage.setCost(serverMessage.getMoneyLeft());
                    }else {
                        decisionMessage.setDecision(DecisionEnum.FOLLOW);
                        decisionMessage.setCost(serverMessage.getCost());
                    }
                    streamUtil.write(outputStream,decisionMessage);
                    System.out.println("跟注成功");
                }else if("b".equals(input) || "B".equals(input)){
                    if (serverMessage.getMoneyLeft() <= serverMessage.getCost()){
                        System.out.println("金额不足无法加注");
                        finish = false;
                        continue;
                    }
                    System.out.println();
                    System.out.println("请输入加注金额，加注范围为0-"+(serverMessage.getMoneyLeft()-serverMessage.getCost()));
                    input = scanner.nextLine();
                    int cost = 0 ;
                    try {
                        cost = Integer.valueOf(input);
                        if (cost < 0 || cost>(serverMessage.getMoneyLeft()-serverMessage.getCost())){
                            throw new RuntimeException("金额超出范围");
                        }
                    }catch (Exception ex){
                        System.out.println("###只能输入整数，或者输入的数据超过金额范围，请重新输入###");
                        finish = false;
                    }
                    ClientMessage decisionMessage = new ClientMessage();
                    decisionMessage.setDecision(DecisionEnum.MAKE_DECISION);
                    decisionMessage.setCost(cost+serverMessage.getCost());
                    streamUtil.write(outputStream,decisionMessage);
                    System.out.println("加注成功");
                }else if("c".equals(input) || "C".equals(input)){
                    ClientMessage decisionMessage = new ClientMessage();
                    decisionMessage.setDecision(DecisionEnum.ABANDON);
                    streamUtil.write(outputStream,decisionMessage);
                    System.out.println("成功放弃，请等待游戏结束");
                }else {
                    System.out.println("###您的输入有误，请重新输入###");
                    finish = false;
                }
            }
        }
    }

    private void printMoney(List<Person> gamers){
        for (int i=0 ; i< gamers.size() ; i++){
            System.out.println(gamers.get(i).getName()+"剩余: "+ gamers.get(i).getMoney()+"元");
        }
    }

    private void regist() throws IOException {
        System.out.println("开始向服务器注册信息，请输入您的姓名");
        System.out.print("姓名:");
        myName = scanner.nextLine();
        ClientMessage clientMessage = new ClientMessage();
        clientMessage.setDecision(DecisionEnum.REGIST);
        clientMessage.setName(myName);
        streamUtil.write(outputStream,clientMessage);
    }

}
